home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / BlitPixie / Sources / BlitPixieScale.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  8.8 KB  |  411 lines  |  [TEXT/CWIE]

  1. //--------------------------------------------------------------------------------------
  2. //    BlitPixieScale
  3. //        scaling blitter
  4. //
  5. //    © Copyright 1997-2000 Anders F Björklund.
  6. //--------------------------------------------------------------------------------------
  7.  
  8. #include "BlitPixieHeader.h"
  9.  
  10. #define FP_SHIFT            16
  11. #define TO_SCREEN            true
  12.  
  13. #ifndef GENERATINGASM // do not include for asm file generation
  14.  
  15. //--------------------------------------------------------------------------------------
  16. //
  17. // Note: these blitters use a combination of Bresenhams (in Y) and Fix-Point (in X)
  18. //       to accomplish the actual scaling. Fastest to do texturemapping like this.
  19. //          It either assembles full longs if writing to screen, or does pixels at once.
  20. //--------------------------------------------------------------------------------------
  21.  
  22. void BlitPixieScale8Bit(
  23.     unsigned char *src,    unsigned long srcBytes,    long width1, long height1, long startu,
  24.     unsigned char *dst,    unsigned long dstBytes,    long width2, long height2, long startv )
  25. {
  26.     unsigned long        u,du;
  27.     unsigned long        out;
  28.     long                x;
  29.     long                errorTerm,error1,error2;
  30.     
  31.      du = (width1 << FP_SHIFT) / width2;
  32.  
  33.     errorTerm =    (startv >> FP_SHIFT) - height2;
  34.     error1 = height1+height1;
  35.     error2 = height2+height2;
  36.  
  37.     dstBytes -= width2;
  38.             
  39.     while( height2-- )
  40.     {
  41.         u = startu;
  42.         
  43.         if ( TO_SCREEN )
  44.         {
  45.                 // do longs
  46.             for (x = 0; x < (width2 >> 2) ; x++)
  47.             {
  48.                 out =              src[(u >> FP_SHIFT)];
  49.                 u += du;
  50.                 out = (out << 8) | src[(u >> FP_SHIFT)];
  51.                 u += du;
  52.                 out = (out << 8) | src[(u >> FP_SHIFT)];
  53.                 u += du;
  54.                 out = (out << 8) | src[(u >> FP_SHIFT)];
  55.                 u += du;
  56.             
  57.                 *((unsigned long *) dst) = out;
  58.                 dst += sizeof(unsigned long);
  59.             }
  60.             
  61.                 // do bytes
  62.             if (width2 & 2)
  63.             {
  64.                 *dst++ = src[(u >> FP_SHIFT)];
  65.                 u += du;
  66.                 *dst++ = src[(u >> FP_SHIFT)];
  67.                 u += du;
  68.             }    
  69.             if (width2 & 1)
  70.             {
  71.                 *dst++ = src[(u >> FP_SHIFT)];
  72.                 u += du;
  73.             }
  74.         }
  75.         else
  76.         {
  77.                 // do bytes
  78.             for (x = 0; x < width2; x++)
  79.             {
  80.                 *dst++ = src[(u >> FP_SHIFT)];
  81.                 u += du;
  82.             }    
  83.         }
  84.         
  85.             // advance to next row(s)
  86.         errorTerm += error1;
  87.         dst = (unsigned char *) ((char *) dst + dstBytes);
  88.           while ( errorTerm > 0 )
  89.         {
  90.               src = (unsigned char *) ((char *) src + srcBytes);
  91.             errorTerm -= error2;
  92.           }
  93.         
  94.     }
  95.  
  96. }
  97.  
  98.  
  99. void BlitPixieScaleMask8Bit(
  100.     unsigned char *src,    unsigned long srcBytes,    long width1, long height1, long startu,
  101.     unsigned char *dst,    unsigned long dstBytes,    long width2, long height2, long startv,
  102.     unsigned char *mask)
  103. {
  104.     unsigned long        u,du;
  105.     unsigned long        outpixel,outmask;
  106.     long                x;
  107.     long                errorTerm,error1,error2;
  108.       
  109.      du = (width1 << FP_SHIFT) / width2;
  110.  
  111.     errorTerm =    (startv >> FP_SHIFT) - height2;
  112.     error1 = height1+height1;
  113.     error2 = height2+height2;
  114.     
  115.     dstBytes -= width2;
  116.             
  117.     while( height2-- )
  118.     {
  119.         u = startu;
  120.         
  121.         if ( TO_SCREEN )
  122.         {
  123.                 // do longs
  124.             for (x = 0; x < (width2 >> 2) ; x++)
  125.             {
  126.                 outmask =                   mask[u >> FP_SHIFT];
  127.                 outpixel =                   src[u >> FP_SHIFT];
  128.                 u += du;
  129.                 outmask =  (outmask << 8) | mask[u >> FP_SHIFT];
  130.                 outpixel = (outpixel << 8) | src[u >> FP_SHIFT];
  131.                 u += du;
  132.                 outmask =  (outmask << 8) | mask[u >> FP_SHIFT];
  133.                 outpixel = (outpixel << 8) | src[u >> FP_SHIFT];
  134.                 u += du;
  135.                 outmask =  (outmask << 8) | mask[u >> FP_SHIFT];
  136.                 outpixel = (outpixel << 8) | src[u >> FP_SHIFT];
  137.                 u += du;
  138.             
  139.                 *((unsigned long *) dst) &= outmask;
  140.                 *((unsigned long *) dst) |= outpixel;
  141.                 dst += sizeof(unsigned long);
  142.             }
  143.             
  144.                 // do bytes
  145.             if (width2 & 2)
  146.             {
  147.                 *dst &= mask[u >> FP_SHIFT];
  148.                 *dst |=  src[u >> FP_SHIFT];
  149.                 u += du;
  150.                 dst++;
  151.                 *dst &= mask[u >> FP_SHIFT];
  152.                 *dst |=  src[u >> FP_SHIFT];
  153.                 u += du;
  154.                 dst++;
  155.             }    
  156.             if (width2 & 1)
  157.             {
  158.                 *dst &= mask[u >> FP_SHIFT];
  159.                 *dst |=  src[u >> FP_SHIFT];
  160.                 u += du;
  161.                 dst++;
  162.             }
  163.         }
  164.         else
  165.         {
  166.                 // do bytes
  167.             for (x = 0; x < width2; x++)
  168.             {
  169.                 *dst &= mask[u >> FP_SHIFT];
  170.                 *dst |=  src[u >> FP_SHIFT];
  171.                 u += du;
  172.                 dst++;
  173.             }
  174.         }
  175.             // advance to next row(s)
  176.         errorTerm += error1;
  177.         dst = (unsigned char *) ((char *) dst + dstBytes);
  178.           while ( errorTerm > 0 )
  179.         {
  180.               src = (unsigned char *) ((char *) src + srcBytes);
  181.             mask = (unsigned char *) ((char *) mask + srcBytes);
  182.             errorTerm -= error2;
  183.           }
  184.         
  185.     }
  186.  
  187. }
  188.  
  189. void BlitPixieScale16Bit(
  190.     unsigned short *src, unsigned long srcBytes,    long width1, long height1, long startu,
  191.     unsigned short *dst, unsigned long dstBytes,    long width2, long height2, long startv )
  192. {
  193.     unsigned long        u,du;
  194.     unsigned long        out;
  195.     long                x;
  196.     long                errorTerm,error1,error2;
  197.       
  198.      du = (width1 << FP_SHIFT) / width2;
  199.  
  200.     errorTerm =    (startv >> FP_SHIFT) - height2;
  201.     error1 = height1+height1;
  202.     error2 = height2+height2;
  203.     
  204.     dstBytes -= width2 + width2;
  205.         
  206.     while( height2-- )
  207.     {
  208.         u = startu;
  209.         
  210.         if ( TO_SCREEN )
  211.         {
  212.                 // do longs
  213.             for (x = 0; x < (width2 >> 1) ; x++)
  214.             {
  215.                 out =               src[(u >> FP_SHIFT)];
  216.                 u += du;
  217.                 out = (out << 16) | src[(u >> FP_SHIFT)];
  218.                 u += du;
  219.                 
  220.                 *((unsigned long *) dst) = out;
  221.                 dst += sizeof(unsigned long);
  222.             }
  223.             
  224.                 // do shorts
  225.             if (width2 & 1)
  226.             {
  227.                 *dst++ = src[(u >> FP_SHIFT)];
  228.                 u += du;
  229.             }
  230.         }
  231.         else
  232.         {
  233.                 // do shorts
  234.             for (x = 0; x < width2; x++)
  235.             {
  236.                 *dst++ = src[(u >> FP_SHIFT)];
  237.                 u += du;
  238.             }
  239.         }
  240.             // advance to next row(s)
  241.         errorTerm += error1;
  242.         dst = (unsigned short *) ((char *) dst + dstBytes);
  243.           while ( errorTerm > 0 )
  244.         {
  245.               src = (unsigned short *) ((char *) src + srcBytes);
  246.             errorTerm -= error2;
  247.           }
  248.         
  249.     }
  250.  
  251. }
  252.  
  253.  
  254. void BlitPixieScaleMask16Bit(
  255.     unsigned short *src, unsigned long srcBytes,    long width1, long height1, long startu,
  256.     unsigned short *dst, unsigned long dstBytes,    long width2, long height2, long startv,
  257.     unsigned short *mask)
  258. {
  259.     unsigned long        u,du;
  260.     unsigned long        outpixel,outmask;
  261.     long                x;
  262.     long                errorTerm,error1,error2;
  263.      
  264.      du = (width1 << FP_SHIFT) / width2;
  265.  
  266.     errorTerm =    (startv >> FP_SHIFT) - height2;
  267.     error1 = height1+height1;
  268.     error2 = height2+height2;
  269.     
  270.     dstBytes -= width2 + width2;
  271.             
  272.     while( height2-- )
  273.     {
  274.         u = startu;
  275.         
  276.         if ( TO_SCREEN )
  277.         {
  278.                 // do longs
  279.             for (x = 0; x < (width2 >> 1) ; x++)
  280.             {
  281.                 outmask =                    mask[u >> FP_SHIFT];
  282.                 outpixel =                    src[u >> FP_SHIFT];
  283.                 u += du;
  284.                 outmask =  (outmask << 16) | mask[u >> FP_SHIFT];
  285.                 outpixel = (outpixel << 16) | src[u >> FP_SHIFT];
  286.                 u += du;
  287.                 
  288.                 *((unsigned long *) dst) &= outmask;
  289.                 *((unsigned long *) dst) |= outpixel;
  290.                 dst += sizeof(unsigned long);
  291.             }
  292.             
  293.                 // do shorts
  294.             if (width2 & 1)
  295.             {
  296.                 *dst &= mask[u >> FP_SHIFT];
  297.                 *dst |=  src[u >> FP_SHIFT];
  298.                 u += du;
  299.                 dst++;
  300.             }
  301.         }
  302.         else
  303.         {
  304.                 // do shorts
  305.             for (x = 0; x < width2; x++)
  306.             {
  307.                 *dst &= mask[u >> FP_SHIFT];
  308.                 *dst |=  src[u >> FP_SHIFT];
  309.                 u += du;
  310.                 dst++;
  311.             }
  312.         }
  313.             // advance to next row(s)
  314.         errorTerm += error1;
  315.         dst = (unsigned short *) ((char *) dst + dstBytes);
  316.           while ( errorTerm > 0 )
  317.         {
  318.               src = (unsigned short *) ((char *) src + srcBytes);
  319.             mask = (unsigned short *) ((char *) mask + srcBytes);
  320.             errorTerm -= error2;
  321.           }
  322.         
  323.     }
  324.  
  325. }
  326.  
  327. void BlitPixieScale32Bit(
  328.     unsigned long *src,    unsigned long srcBytes,    long width1, long height1, long startu,
  329.     unsigned long *dst,    unsigned long dstBytes,    long width2, long height2, long startv )
  330. {
  331.     unsigned long        u,du;
  332.     long                x;
  333.     long                errorTerm,error1,error2;
  334.       
  335.      du = (width1 << FP_SHIFT) / width2;
  336.  
  337.     errorTerm =    (startv >> FP_SHIFT) - height2;
  338.     error1 = height1+height1;
  339.     error2 = height2+height2;
  340.     
  341.     dstBytes -= width2 << 2;
  342.             
  343.     while( height2-- )
  344.     {
  345.         u = startu;
  346.         
  347.             // do longs
  348.         for (x = 0; x < width2; x++)
  349.         {
  350.             *dst++ = src[(u >> FP_SHIFT)];
  351.             u += du;
  352.         }
  353.         
  354.             // advance to next row(s)
  355.         errorTerm += error1;
  356.         dst = (unsigned long *) ((char *) dst + dstBytes);
  357.           while ( errorTerm > 0 )
  358.         {
  359.               src = (unsigned long *) ((char *) src + srcBytes);
  360.             errorTerm -= error2;
  361.           }
  362.     }
  363.  
  364. }
  365.  
  366.  
  367. void BlitPixieScaleMask32Bit(
  368.     unsigned long *src,    unsigned long srcBytes,    long width1, long height1, long startu,
  369.     unsigned long *dst,    unsigned long dstBytes,    long width2, long height2, long startv,
  370.     unsigned long *mask)
  371. {
  372.     unsigned long        u,du;
  373.     long                x;
  374.     long                errorTerm,error1,error2;
  375.       
  376.      du = (width1 << FP_SHIFT) / width2;
  377.  
  378.     errorTerm =    (startv >> FP_SHIFT) - height2;
  379.     error1 = height1+height1;
  380.     error2 = height2+height2;
  381.     
  382.     dstBytes -= width2 << 2;
  383.             
  384.     while( height2-- )
  385.     {
  386.         u = startu;
  387.         
  388.             // do longs
  389.         for (x = 0; x < width2; x++)
  390.         {
  391.             *dst &= mask[u >> FP_SHIFT];
  392.             *dst |=  src[u >> FP_SHIFT];
  393.             u += du;
  394.             dst++;
  395.         }
  396.         
  397.             // advance to next row(s)
  398.         errorTerm += error1;
  399.         dst = (unsigned long *) ((char *) dst + dstBytes);
  400.           while ( errorTerm > 0 )
  401.         {
  402.               src = (unsigned long *) ((char *) src + srcBytes);
  403.             mask = (unsigned long *) ((char *) mask + srcBytes);
  404.             errorTerm -= error2;
  405.           }
  406.     }
  407.  
  408. }
  409.  
  410. #endif
  411.